	package LocalServerTcp;
import java.net.Socket;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;

import generalClasses.*;

import java.io.*;

import LeaderElection.TempRunLocalServer;

import udpKuponServer.CenterMulticastServer;
import udpKuponServer.MulticastServerThread;
import udpKuponServer.NorthMulticastServer;
import udpKuponServer.SouthMulticastServer;

import mySQLHandlers.MysqlConnect;

import connection.protocols.*;

public class LocalKuponsMultiServerThread  extends Thread  {
	
	private Socket socket = null;
	private Server localServer = null;
	
	public LocalKuponsMultiServerThread(Socket socket,Server northServer) 
		{
	    	super("KKMultiServerThread");
	    	this.socket = socket;
	    	this.localServer = northServer;

	    }
    public void run() {
    	try {
    		// Open relevant socket & buffers
    		PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    		BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    		ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
    		ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
    		
    		String  outputLine;
    		String action = null;
    		
    		// Read user request
    		action=in.readLine();
    		// Handle user request
    		// Kupon request
    		if (action.equalsIgnoreCase("KUPON_REQUEST"))
    		{
    			outputLine="SEND_REQUEST";
    			out.println(outputLine);
    			this.get_kupons(out, in, ois, oos);
    		}
    		// Kupon Purchase
    		if (action.equalsIgnoreCase("PURCHASE_KUPON"))
    		{
    			outputLine="SEND_KUPON_ID";
    			out.println(outputLine);
    			this.purchase_kupons(out, in, ois, oos);
    		}
    		if (action.equalsIgnoreCase("PURCHASE_HISTORY"))
    		{
    			outputLine="SEND_TIME";
    			out.println(outputLine);
    			this.purchase_history(out, in, ois, oos);
    		}
    		if (action.equalsIgnoreCase("RELEVANT_KUPONS"))
    		{
    			outputLine="SEND_NUMBER";
    			out.println(outputLine);
    			this.relevant_kupons(out, in, ois, oos);
    		}
    		if (action.equalsIgnoreCase("NUM_OF_MSG_SENT"))
    		{
    			if (localServer.getRegion()== ProgramData.NORTH)
    			{
//    				String numOfMsgs=String.valueOf(NorthMulticastServer.numOfMsgsSent);
    				
    				String numOfMsgs = String.valueOf( TempRunLocalServer.numOfMsgsSentNorth );
    				out.write(numOfMsgs);
    			}
    			if (localServer.getRegion()== ProgramData.CENTER)
    			{
//        			String numOfMsgs=String.valueOf(CenterMulticastServer.numOfMsgsSent);
    				
    				String numOfMsgs = String.valueOf( TempRunLocalServer.numOfMsgsSentCenter );
        			out.write(numOfMsgs);
    			}
    			if (localServer.getRegion()== ProgramData.SOUTH)
    			{
//        			String numOfMsgs=String.valueOf(SouthMulticastServer.numOfMsgsSent);
    				
    				String numOfMsgs = String.valueOf( TempRunLocalServer.numOfMsgsSentSouth );
        			out.write(numOfMsgs);
    			}
    			
    		}
    		// Close relevant socket & buffers
	    	out.close();
	    	in.close();
	    	ois.close();
	    	socket.close();
    	}

    	catch (IOException e) {
    		e.printStackTrace();
    	} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }


/**
     * The Function receive request for Kupon Query and returns relevant Kupons details
     * @param out - print writer object (string) to output buffer
     * @param in - Buffer reader object (string) to input buffer
     * @param ois - print writer object to input buffer
     * @param oos - print writer object to output buffer
     * @return succFlag - True \ False
*/
private boolean get_kupons(PrintWriter out, BufferedReader in,
		ObjectInputStream ois, ObjectOutputStream oos) 
{
	boolean succFlag=false;
	try 
	{
		CouponForQuery inputLine;
		ResultSet outputLine;
		ArrayList<Coupon> localCouponsList = new ArrayList<Coupon>();
		inputLine=(CouponForQuery)ois.readObject();
		out.println("SENDING_QUERY_RESULT");
		outputLine=MysqlConnect.getActiveCoupns(inputLine,localServer.getRegion());
		
		//Creating array of Kupons
		while (outputLine.next())
		{
			Coupon cop= new Coupon(outputLine.getInt("ID"),1,
								   outputLine.getInt("category"),
								   outputLine.getInt("region"),
								   outputLine.getString("businessName"),
								   outputLine.getString("productName"),
								   outputLine.getString("businessCity"),
								   outputLine.getString("expirationDate"),
								   outputLine.getInt("discountAmount"),
								   outputLine.getInt("couponPrice"));
			localCouponsList.add(cop);
		}
		oos.flush();
		//Sending the array to the Client
		oos.writeObject(localCouponsList);		
		succFlag=true;
	}
	catch (IOException e) {
		e.printStackTrace();
		System.out.println(e.getMessage());
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
		System.out.println(e.getMessage());
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return succFlag;
}

/**
 * The function receive purchase  request and if success insert it to the DB 
 * @param out - print writer object (string) to output buffer
 * @param in - Buffer reader object (string) to input buffer
 * @param ois - print writer object to input buffer
 * @param oos - print writer object to output buffer
 * @return succFlag - True \ False
 * @throws SQLException
 */
private boolean purchase_kupons(PrintWriter out, BufferedReader in,
		ObjectInputStream ois, ObjectOutputStream oos) throws SQLException 
{
	boolean succFlag=false;
	try 
	{
		String outputLine,inputLine;
		inputLine=in.readLine();
		int id=Integer.parseInt(inputLine);
		
		outputLine="SEND_USERNAME";
		out.println(outputLine);
		inputLine=in.readLine();
		
		//Checking Kupon Validity
		if (MysqlConnect.checkCouponId(id,localServer.getRegion()))
		{
			//Creating purchase line in DB
			int temp=MysqlConnect.createPurchase(inputLine,id,localServer.getRegion());
			if (temp != (-1))
			{
				String str=Integer.toString(temp);
				out.println("PURCHASE_SUCCESS_PURCHASE_ID: "+str);
				return succFlag=true;
			}
			else
			{
				out.println("PURCHASE_FAIL");	
			}
		}
		else
		{
			out.println("PURCHASE_FAIL");
		}
		
	}
	catch (IOException e) {
		e.printStackTrace();
		System.out.println(e.getMessage());
	}
	return succFlag;
}
/**
     * The function receive purchase history request and returns the relevant purchase history 
     * @param out - print writer object (string) to output buffer
     * @param in - Buffer reader object (string) to input buffer
     * @param ois - print writer object to input buffer
     * @param oos - print writer object to output buffer
     * @return succFlag - True \ False
 */
private boolean purchase_history(PrintWriter out, BufferedReader in,
		ObjectInputStream ois, ObjectOutputStream oos) 
{

	boolean succFlag=false;
	try 
	{
		String inputLine=null;
		ResultSet outputLine;
		ArrayList<PurchaseType> purchaseList = new ArrayList<PurchaseType>();
		
		inputLine=in.readLine();
		Long time = Long.valueOf(inputLine);

		outputLine=MysqlConnect.getPurchaseHistory(time,localServer.getRegion());
		
		//Creating array of Kupons
		while (outputLine.next())
		{
			PurchaseType temp= new PurchaseType(outputLine.getString("purchaseDate"),
												outputLine.getInt("purchaseId"),
												outputLine.getString("userName"),
												outputLine.getString("productName"),
												outputLine.getString("couponPrice"),
												outputLine.getInt("couponId"));
			purchaseList.add(temp);
		}
		if (purchaseList.size()!=0)
		{
			out.println("SENDING_PURCHASE_HISTORY");
			//Sending the array to the Client
			oos.writeObject(purchaseList);		
			succFlag=true;
		}
		else
		{
			out.println("NO_HISTORY_OF_PURCHASING");
		}
	}
	catch (IOException e) {
		e.printStackTrace();
		System.out.println(e.getMessage());
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return succFlag;
}
private boolean relevant_kupons(PrintWriter out, BufferedReader in,
		ObjectInputStream ois, ObjectOutputStream oos) 
{

	boolean succFlag=false;
	try 
	{
		String inputLine=null;
		ResultSet outputLine;
		ArrayList<Coupon> couponList = new ArrayList<Coupon>();
		
		inputLine=in.readLine();
		int num = Integer.valueOf(inputLine);

		outputLine=MysqlConnect.getRecentExpiryCopuns(num,localServer.getRegion());
		
		//Creating array of Kupons
		while (outputLine.next())
		{
			Coupon temp= new Coupon(outputLine.getInt("id"),
									ProgramData.STILL_AVAILABLE,
									outputLine.getInt("category"),
									outputLine.getInt("region"),
									outputLine.getString("businessName"),
									outputLine.getString("productName"),
									outputLine.getString("businessCity"),
									outputLine.getString("expirationDate"),
									outputLine.getInt("discountAmount"),
									outputLine.getInt("couponPrice"));		
			couponList.add(temp);
		}
		if (couponList.size()!=0)
		{
			out.println("SENDING_RELEVANT_KUPONS");
			//Sending the array to the Client
			oos.writeObject(couponList);		
			succFlag=true;
		}
		else
		{
			out.println("NO_RELEVANT_KUPONS");
		}
	}
	catch (IOException e) {
		e.printStackTrace();
		System.out.println(e.getMessage());
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return succFlag;
}
}

